package io.renren.modules.substation.service.impl;

import io.renren.modules.substation.entity.TInfoDevInfoEntity;
import io.renren.modules.substation.entity.TInfoRoleAreaEntity;
import io.renren.modules.sys.entity.SysUserEntity;
import io.renren.modules.sys.service.impl.SysUserRoleServiceImpl;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.*;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import io.renren.common.utils.PageUtils;
import io.renren.common.utils.Query;
import io.renren.modules.substation.dao.TInfoAreaInfoDao;
import io.renren.modules.substation.entity.TInfoAreaInfoEntity;
import io.renren.modules.substation.service.TInfoAreaInfoService;
import org.springframework.transaction.annotation.Transactional;


@Service("tInfoAreaInfoService")
public class TInfoAreaInfoServiceImpl extends ServiceImpl<TInfoAreaInfoDao, TInfoAreaInfoEntity> implements TInfoAreaInfoService {

    @Autowired
    private TInfoDevInfoServiceImpl tInfoDevInfoServiceImpl;
    @Autowired
    private TInfoRoleAreaServiceImpl tInfoRoleAreaServiceImpl;
    @Autowired
    private SysUserRoleServiceImpl sysUserRoleServiceImpl;

    private static boolean cacheAreaInfoFlag = false;
    private static Map<Long, TInfoAreaInfoEntity> SysCacheAreaMap;
    private static Map<Long, String> SysCacheAreaNameMap;
    private static Map<Long, String> SysCacheAreaSubAreaMap;
    private static List<TInfoAreaInfoEntity> SysCacheAreaList;


    protected SysUserEntity getUser() {
        return (SysUserEntity) SecurityUtils.getSubject().getPrincipal();
    }

    @Override
    public PageUtils queryPage(Map<String, Object> params) {
        List<Long> areaList = tInfoRoleAreaServiceImpl.getAreaListByUser(getUser().getUserId());
        String areaName = (String)params.get("areaName");
        Long areaId = params.get("areaId") != null ? Long.parseLong(params.get("areaId").toString()) : null;
        Long parentAreaCode = params.get("parentAreaCode") != null ? Long.parseLong(params.get("parentAreaCode").toString()) : null;

        IPage<TInfoAreaInfoEntity> page = this.page(
                new Query<TInfoAreaInfoEntity>().getPage(params),
                new QueryWrapper<TInfoAreaInfoEntity>()
                        .like(StringUtils.isNotBlank(areaName),"AREA_NAME", areaName)
                        .eq(areaId != null,"AREA_ID", areaId)
                        .eq(parentAreaCode != null,"PARENT_AREA_CODE", parentAreaCode)
                        .in(areaList != null && areaList.size() > 0, "AREA_ID", areaList)
        );

        return new PageUtils(page);
    }

    @Override
    @Transactional
    public void saveArea(TInfoAreaInfoEntity tInfoAreaInfo) {
        tInfoAreaInfo.setCreateTime(new Date());
        this.save(tInfoAreaInfo);
        //新增区域信息时，还需将该区域的观看权限添加到当前用户所属的角色中
        List<Long> userRoleList = sysUserRoleServiceImpl.queryRoleIdList(getUser().getUserId());
        TInfoRoleAreaEntity tInfoRoleAreaEntity = new TInfoRoleAreaEntity();
        for (Long role : userRoleList) {
            tInfoRoleAreaEntity.setRoleId(role);
            tInfoRoleAreaEntity.setRoleArea(tInfoAreaInfo.getAreaId());
            tInfoRoleAreaEntity.setAreaType("0");
            tInfoRoleAreaEntity.setCreateOpr(getUser().getUserId());
            tInfoRoleAreaEntity.setCreateTime(new Date());
            tInfoRoleAreaServiceImpl.save(tInfoRoleAreaEntity);
        }
        cacheAreaInfoFlag = false;
    }

    /**
     * 获取带观看权限的区域列表
     */
    @Override
    public List<TInfoAreaInfoEntity> listByUserPerms() {
        List<Long> areaList = tInfoRoleAreaServiceImpl.getAreaListByUser(getUser().getUserId());
        List<TInfoAreaInfoEntity> list = baseMapper.selectList(
                new QueryWrapper<TInfoAreaInfoEntity>()
                        .in(areaList != null && areaList.size() > 0, "AREA_ID", areaList)
        );
        return list;
    }

    /**
     * 获取带观看权限的区域列表-指定areaId
     */
    @Override
    public TInfoAreaInfoEntity getAreaInfoUserPerms(Long areaId) {
        List<Long> areaList = tInfoRoleAreaServiceImpl.getAreaListByUser(getUser().getUserId());
        TInfoAreaInfoEntity info = null;
        if (areaList.contains(areaId))
            info = baseMapper.selectById(areaId);
//        TInfoAreaInfoEntity info = baseMapper.selectOne(
//                new QueryWrapper<TInfoAreaInfoEntity>()
//                        .in(areaList != null && areaList.size() > 0, "AREA_ID", areaList)
//                        .eq(areaId != null, "AREA_ID", areaId)
//        );
        return info;
    }


    /**
     * 获取areaType=0即只包含普通区域的区域列表
     */
    @Override
    public List<TInfoAreaInfoEntity> queryOnlyAreaList() {
        List<Long> areaList = tInfoRoleAreaServiceImpl.getAreaListByUser(getUser().getUserId());
        List<TInfoAreaInfoEntity> list = baseMapper.selectList(
                new QueryWrapper<TInfoAreaInfoEntity>()
                        .eq("AREA_TYPE", "0")
                        .in(areaList != null && areaList.size() > 0, "AREA_ID", areaList)
        );
        return list;
    }

    /**
     * 获取areaType=1即只包含配电房的区域列表
     */
    @Override
    public List<TInfoAreaInfoEntity> getStationList() {
        List<Long> areaList = tInfoRoleAreaServiceImpl.getAreaListByUser(getUser().getUserId());
        List<TInfoAreaInfoEntity> list = baseMapper.selectList(
                new QueryWrapper<TInfoAreaInfoEntity>()
                        .eq("AREA_TYPE", "1")
                        .in(areaList != null && areaList.size() > 0, "AREA_ID", areaList)
        );
        return list;
    }

    /**
     * 获取areaType=2即只包含被监控设备列表
     */
    @Override
    public List<TInfoAreaInfoEntity> getAreaDevList() {
        List<Long> areaList = tInfoRoleAreaServiceImpl.getAreaListByUser(getUser().getUserId());
        List<TInfoAreaInfoEntity> list = baseMapper.selectList(
                new QueryWrapper<TInfoAreaInfoEntity>()
                        .eq("AREA_TYPE", "2")
                        .in(areaList != null && areaList.size() > 0, "AREA_ID", areaList)
        );
        return list;
    }

    @Override
    public List<TInfoAreaInfoEntity> queryOnlyAreaStaList() {
        List<Long> areaList = tInfoRoleAreaServiceImpl.getAreaListByUser(getUser().getUserId());
        String[] areaType = {"0", "1"};
        List<TInfoAreaInfoEntity> list = baseMapper.selectList(
                new QueryWrapper<TInfoAreaInfoEntity>()
                        .in("AREA_TYPE", areaType)
                        .in(areaList != null && areaList.size() > 0, "AREA_ID", areaList)
        );
        return list;
    }

    @Override
    public void removeByIdAndRmoveDevInfo(Long[] areaIds, Long userId) {
        for (Long areaId : areaIds){
            baseMapper.deleteById(areaId);//删除区域信息
            TInfoDevInfoEntity o = new TInfoDevInfoEntity();
            o.setDevArea(areaId);
            o.setLastOpr(userId);
            o.setLastTime(new Date());
            tInfoDevInfoServiceImpl.setAreaNullByAreaId(o);
        }
    }

    @Override
    public List<TInfoAreaInfoEntity> getAreaList() {
        List<Long> areaList = tInfoRoleAreaServiceImpl.getAreaListByUser(getUser().getUserId());
        List<TInfoAreaInfoEntity> list = baseMapper.selectList(
                new QueryWrapper<TInfoAreaInfoEntity>()
                        .eq("AREA_TYPE", "0")
                        .in(areaList != null && areaList.size() > 0, "AREA_ID", areaList)
        );
        return list;
    }

    @Override
    public List<TInfoAreaInfoEntity> selectSubAreaById(Long areaId){
        List<TInfoAreaInfoEntity> list = new ArrayList<>();
        String subAreaStr = getSubAreaList(areaId);
        if (subAreaStr != null && subAreaStr.length() > 0){
            subAreaStr = subAreaStr + ",";
            List<Long> areaList = tInfoRoleAreaServiceImpl.getAreaListByUser(getUser().getUserId());
            List<Long> _areaList = new ArrayList<>();
            for (Long s : areaList){
                if (subAreaStr.contains(s +",")){
                    _areaList.add(s);
                }
            }
            if (_areaList.contains(areaId))
                _areaList.remove(areaId);
            list = baseMapper.selectList(
                    new QueryWrapper<TInfoAreaInfoEntity>()
                            .in(areaList != null && areaList.size() > 0, "AREA_ID", _areaList)
            );
        }
        return list;
    }

    @Override
    public Map<Long, String> getAreaNameMap() {
        if (!cacheAreaInfoFlag) {
            refleshAreaInfoAll();
        }
        return SysCacheAreaNameMap;
    }

    @Override
    public Map<Long, String> getAreaSubAreaMap() {
        if (!cacheAreaInfoFlag) {
            refleshAreaInfoAll();
        }
        return SysCacheAreaSubAreaMap;
    }

    @Override
    public String getAreaSubAreaInfo(Long areaId) {
        if (!cacheAreaInfoFlag) {
            refleshAreaInfoAll();
        }
        return SysCacheAreaSubAreaMap.get(areaId);
    }


    @Override
    public String getSubAreaList(Long areaId) {
        Map<String, Object> params = new HashMap<>();
        params.put("areaId", areaId);
        return baseMapper.getSubAreaList(params);
    }

    public void refleshAreaInfoAll() {
        Map<Long, TInfoAreaInfoEntity> map = new HashMap<>();
        List<TInfoAreaInfoEntity> list = baseMapper.selectList(new QueryWrapper<>());
        for (TInfoAreaInfoEntity obj : list) {
            map.put(obj.getAreaId(), obj);
        }
        SysCacheAreaMap = map;
        SysCacheAreaList = list;
        cacheAreaInfoFlag = true;

        Map<Long, String> areaNameMap = new HashMap<>();
        for (TInfoAreaInfoEntity o : list) {
            areaNameMap.put(o.getAreaId(), o.getAreaName());
        }
        SysCacheAreaNameMap = areaNameMap;

        Map<Long, String> subAreaMap = new HashMap<>();
        for (TInfoAreaInfoEntity o : list) {
            String subAreaList = getSubAreaList(o.getAreaId());
            subAreaMap.put(o.getAreaId(), subAreaList);
        }
        SysCacheAreaSubAreaMap = subAreaMap;
    }

}